home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-21 | 6.3 KB | 246 lines | [TEXT/CWIE] |
- unit MyHistory;
-
- { Edit history}
- { 9 Dec 95 pnl Original}
- { 8 Apr 96 jc Add bits for marking which downstream servers were offered this message }
- { 9 Apr 96 jc Adjust ReadEntry to account for longer EntryRecord }
- {11 Apr 96 jc Fix bug in markMsgSent (reading too many bytes & clobbering data on write }
- {14 Apr 96 jc Added markMsgNotSent }
- {25 May 96 jc Added HistoryAfterStep }
-
- interface
-
- uses
- Types, Files;
-
- const
- H_Null = $12345678;
- H_FromStart = $80000000;
-
- function HistoryCreate (var fs: FSSpec): OSErr;
- { You should create the file before calling this using FSpCreate. Any existing data will be destroyed. }
- function HistoryOpen (var fs: FSSpec; var refnum: longint): OSErr;
- function HistoryFlush (refnum: longint): OSErr;
- function HistoryClose (refnum: longint): OSErr;
- function HistoryAdd (refnum: longint; data: Str255): OSErr;
- function HistoryAfter (refnum: longint; time: longint; var id: longint): OSErr;
- function HistoryAfterStep(refnum: longint; time: longint; var id: longint; var maxtime: integer): OSErr;
- function HistoryNext (refnum: longint; var id: longint; var time: longint; var offered: longint; var data: Str255): OSErr;
- function HistoryExpire (refnum: longint; time: longint): OSErr;
- function msgSentP(offered: longint; idx: integer): boolean;
- procedure markMsgSent(refnum: longint; pos: longint; idx: integer);
- procedure markMsgNotSent(refnum: longint; pos: longint; idx: integer);
- implementation
-
- uses
- Errors, OSUtils,
- MyFileSystemUtils, MyMemory, MyMathUtils;
-
- { File format: }
- { sequence of entries }
- { Entry format: }
- { time:longint }
- { offered: longint }
- { data:PString }
- { zero:byte }
-
- {$PUSH}
- {$ALIGN MAC68K}
-
- const
- EROverhead = 4+4+1; { this must be adjusted to match the position of the 1st byte of Data in the HistoryRecord }
- type
- HistoryRecord = record
- time: longint; { time message added }
- offered: longint; { bit mask of servers offered this message }
- data: Str255; { message ID }
- zero: byte;
- end;
-
- {$ALIGN RESET}
- {$POP}
-
- function HistoryCreate (var fs: FSSpec): OSErr;
- var
- err, oerr: OSErr;
- rn: integer;
- begin
- err := FSpOpenDF(fs, fsRdWrPerm, rn);
- if err = noErr then begin
- err := SetEOF(rn, 0);
- oerr := FSClose(rn);
- if err = noErr then
- err := oerr;
- end;
- HistoryCreate := err;
- end;
-
- function HistoryOpen (var fs: FSSpec; var refnum: longint): OSErr;
- var
- err, junk: OSErr;
- rn: integer;
- begin
- err := FSpOpenDF(fs, fsRdWrPerm, rn);
- if err = noErr then begin
- if err <> noErr then begin
- junk := FSClose(rn);
- end;
- end;
- refnum := rn;
- if err <> noErr then begin
- refnum := H_Null;
- end;
- HistoryOpen := err;
- end;
-
- function HistoryFlush (refnum: longint): OSErr;
- var
- err: OSErr;
- pb: ParamBlockRec;
- begin
- pb.ioRefNum := refnum;
- err := PBFlushFileSync(@pb);
- HistoryFlush := err;
- end;
-
- function HistoryClose (refnum: longint): OSErr;
- var
- err: OSErr;
- begin
- if refnum <> H_Null then begin
- err := FSClose(refnum);
- end;
- HistoryClose := err;
- end;
-
- function HistoryAdd (refnum: longint; data: Str255): OSErr;
- var
- err: OSErr;
- er: HistoryRecord;
- begin
- MFill(@er, SizeOf(er), 0);
- GetDateTime(er.time);
- er.data := data;
- er.offered := 0;
- err := MyFSWriteAt(refnum, fsFromLEOF, 0, EROverhead + length(data), @er);
- HistoryAdd := err;
- end;
-
- function ReadEntry (refnum: longint; var pos: longint; var entry: HistoryRecord): OSErr;
- var
- err: OSErr;
- begin
- err := MyFSReadAt(refnum, pos, EROverhead, @entry); { read enough of the record to get string length }
- if err = noErr then begin
- err := MyFSReadAt(refnum, pos, EROverhead + length(entry.data), @entry); { now read entire record }
- end;
- if err = noErr then begin
- pos := pos + EROverhead + length(entry.data);
- end;
- ReadEntry := err;
- end;
-
- function HistoryAfter (refnum: longint; time: longint; var id: longint): OSErr;
- var
- err: OSErr;
- pos: longint;
- entry: HistoryRecord;
- begin
- pos := 0;
- repeat
- id := pos;
- err := ReadEntry(refnum, pos, entry);
- until (err <> noErr) or (entry.time >= time);
- HistoryAfter := err;
- end;
-
- function HistoryAfterStep(refnum: longint; time: longint; var id: longint; var maxtime: integer): OSErr;
- var
- err: OSErr;
- pos: longint;
- entry: HistoryRecord;
- start, now: longint;
- begin
- pos := id;
- GetDateTime(start);
- repeat
- id := pos;
- err := ReadEntry(refnum, pos, entry);
- GetDateTime(now);
- until (err <> noErr) or (entry.time >= time) or ((start+maxtime)<now);
- if ((start+maxtime)<now) then maxtime := -maxtime; { let caller know it timed out }
- HistoryAfterStep := err;
- end;
-
- function HistoryNext (refnum: longint; var id: longint; var time: longint; var offered: longint; var data: Str255): OSErr;
- var
- err: OSErr;
- entry: HistoryRecord;
- begin
- err := ReadEntry(refnum, id, entry);
- time := entry.time;
- offered := entry.offered;
- data := entry.data;
- HistoryNext := err;
- end;
-
- function HistoryExpire (refnum: longint; time: longint): OSErr;
- var
- err: OSErr;
- src, dst, len, cnt: longint;
- buffer: packed array[1..8192] of Byte;
- begin
- err := HistoryAfter(refnum, time, src);
- if err = noErr then begin
- err := GetEOF(refnum, len);
- if err = noErr then begin
- len := len - src;
- dst := 0;
- while (err = noErr) & (len > 0) do begin
- cnt := Min(len, SizeOf(buffer));
- err := MyFSReadAt(refnum, src, cnt, @buffer);
- if err = noErr then begin
- err := MyFSWriteAt(refnum, fsFromStart, dst, cnt, @buffer);
- end;
- src := src + cnt;
- dst := dst + cnt;
- len := len - cnt;
- end;
- end;
- end else if err = eofErr then begin
- err := SetEOF(refnum, 0);
- end;
- HistoryExpire := err;
- end;
-
- function msgSentP(offered: longint; idx: integer): boolean;
- begin
- msgSentP := BTst(offered, idx);
- end;
-
- procedure markMsgSent(refnum: longint; pos: longint; idx: integer);
- var
- err: OSErr;
- entry: HistoryRecord;
- begin
- err := MyFSReadAt(refnum, pos, EROverhead, @entry);
- if err = noErr then begin
- BSet(entry.offered, idx);
- err := MyFSWriteAt(refnum, fsFromStart, pos, EROverhead, @entry);
- end;
- end;
-
- procedure markMsgNotSent(refnum: longint; pos: longint; idx: integer);
- var
- err: OSErr;
- entry: HistoryRecord;
- begin
- err := MyFSReadAt(refnum, pos, EROverhead, @entry);
- if err = noErr then begin
- BClr(entry.offered, idx);
- err := MyFSWriteAt(refnum, fsFromStart, pos, EROverhead, @entry);
- end;
- end;
-
- end.
-